import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author : lizhifeng
 * @create 2022/8/17 16:09
 * @DESC 2022/8/17 16:09
 */


public class Miner {


    public static byte[] buildMerkleRoot(List<TransactionId> toBeConfirm) {

        List<TransactionId> itemArray = new ArrayList<>(toBeConfirm);

        while (itemArray.size() > 1) {

            ArrayList<TransactionId> tmp = new ArrayList<>();
            int size = itemArray.size();

            if ((size & 1) == 1) {
                itemArray.add(itemArray.get(size - 1));
            }

            int half = itemArray.size() >>> 1;

            for (int i = 0; i < half; i++) {
                byte[] hash1 = itemArray.get(i).getHash();
                byte[] hash2 = itemArray.get(i + 1).getHash();

                byte[] bytes = new byte[64];
                System.arraycopy(hash1, 0, bytes, 0, 32);
                System.arraycopy(hash2, 0, bytes, 32, 32);
                byte[] newHash = Hash256.hash(bytes);
                tmp.add(new TransactionId(newHash));
            }

            itemArray = tmp;
        }

        return itemArray.get(0).getHash();
    }


    public static boolean mining(Header header) throws IOException {


        ByteBuffer buffer = ByteBuffer.allocate(80);
        buffer.putInt(header.getVersion())
                .put(header.getPreHash())
                .put(header.getMerkleRoot())
                .putInt(header.getTime())
                .putInt(header.getBits());
        byte[] result = new byte[80];

        for (int i = 0; true; i++) {

            if (i % 1000000 == 0) {
                System.out.println("mining" + i);
            }

            buffer.position(76);
            buffer.putInt(i);
            buffer.position(0);
            buffer.get(result, 0, 80);
            byte[] hash = Hash256.hash(result);
            hash = Hash256.hash(hash);

            // 前导0的个数恰好是nbit
            if (Hash256.nbit(hash) == header.getBits()) {
                header.setNonce(i);
                break;
            }

            if (i == Integer.MAX_VALUE) {
                System.out.println("挖矿结束,没有找到合适的nonce值！！！");
                return false;
            }
        }

        return true;
    }


}
